<!--
 * @Author: yanjikun
 * @Date: 2022-04-25 15:32:18
 * @LastEditors: yanjikun
 * @LastEditTime: 2022-05-12 16:19:28
 * @Description: file content
-->
<template>
  <div>
    <Input v-bind="getProps" :value="address">
      <template #addonAfter>
        <EnvironmentOutlined class="cursor-pointer" @click="handleMapModal" />
      </template>
    </Input>
    <ModalRender></ModalRender>
  </div>
</template>

<script setup lang="tsx">
  import { useVModel } from '@vueuse/core'
  import { Input } from 'ant-design-vue'
  import { computed, ref, unref, watch } from 'vue'
  import { addressSelectProps } from '../types/components'
  import { EnvironmentOutlined } from '@ant-design/icons-vue'
  import { useModal } from '@/hooks/useModal/useModal'
  import { Form } from 'ant-design-vue'
  interface Emits {
    (event: 'update:value', val: Recordable): void
  }
  interface markerType {
    id: number
    position: [number, number]
  }
  defineOptions({
    name: 'AddressSelect',
  })
  const props = defineProps(addressSelectProps)
  const emit = defineEmits<Emits>()
  const [ModalRender] = useModal()
  const getProps = computed(() => {
    return { ...props, disabled: true } as Recordable
  })
  const modelValue = useVModel(props, 'value', emit)
  const address = computed(() => {
    return unref(modelValue)?.[props.addressField] as string
  })
  const center = ref<[number, number]>([104.06, 30.67])
  const markers = ref<markerType[]>([])
  const detailAddress = ref('')
  const searchValue = ref('')
  /**点击地图回调函数 */
  const handleMapClick = (e: { lnglat: AMap.AMapLocation }) => {
    const { lnglat } = e
    markers.value = [
      {
        position: [lnglat.lng, lnglat.lat],
        id: 1,
      },
    ]
    getDetailAddress()
  }
  /**通过经纬度获取详细地址 */
  const getDetailAddress = () => {
    AMap.plugin('AMap.Geocoder', () => {
      let GeocoderOptions = {
        city: '全国',
      }
      let geocoder = new AMap.Geocoder(GeocoderOptions)
      geocoder.getAddress(unref(markers)[0]?.position, (status, result) => {
        if (status === 'complete' && result.info === 'OK') {
          detailAddress.value = result.regeocode.formattedAddress
        } else {
          detailAddress.value = '无法获取地址'
        }
      })
    })
  }
  /**初始化详细地址，标记和搜索POI */
  const initDefaultData = () => {
    const _modelValue = unref(modelValue)
    const { addressField, lngField, latField } = props
    detailAddress.value = _modelValue?.[addressField]
    markers.value =
      _modelValue?.[lngField] && _modelValue?.[latField]
        ? [
            {
              position: [_modelValue?.[lngField], _modelValue?.[latField]],
              id: 1,
            },
          ]
        : []
    searchValue.value = ''
  }
  /**选择POI回调函数 */
  const handleSelectPoi = (e: AMap.SearchPOIEvent) => {
    searchValue.value = e.poi.name
    handleMapClick({ lnglat: e.poi.location })
  }
  /**显示选择地址Modal */
  const handleMapModal = () => {
    ModalRender.show({
      title: '选择地址',
      width: '1000px',
      maskClosable: false,
      destroyOnClose: true,
      content: () => {
        const props = {
          viewMode: '3D',
          pitch: 30,
          zoom: 30,
          center: unref(markers)[0]?.position ?? unref(center),
          onClick: handleMapClick,
        }
        const searchProps = {
          onSelect: handleSelectPoi,
          onChoose: handleSelectPoi,
          inputId: 'searchBox',
          outputId: 'AmapSearchResult',
          visible: false,
        }
        return (
          <div class="h-500px flex flex-col relative">
            <el-amap {...props} class="flex-1">
              {unref(markers).map((item) => (
                <el-amap-marker key={item.id} position={item.position}></el-amap-marker>
              ))}
              <el-amap-search-box {...searchProps} />
            </el-amap>
            <div class="mt-2">
              <Form.ItemRest>
                <Input v-model:value={detailAddress.value}></Input>
              </Form.ItemRest>
            </div>
            <div class="absolute left-326px top-8px w-300px">
              <Form.ItemRest>
                <Input id="searchBox" v-model:value={searchValue.value}></Input>
              </Form.ItemRest>
            </div>
            <div
              id="AmapSearchResult"
              class="absolute left-326px top-40px w-300px bg-white border border-gray-200"
            ></div>
          </div>
        )
      },
      onOk: () => {
        const lnglat = unref(markers)?.[0]
        if (!lnglat) {
          modelValue.value = undefined
          return
        }
        modelValue.value = {
          [props.addressField]: unref(detailAddress),
          [props.lngField]: lnglat.position[0],
          [props.latField]: lnglat.position[1],
        }
      },
      onCancel: () => {
        initDefaultData()
      },
    })
  }
  watch(
    () => modelValue,
    () => {
      initDefaultData()
    },
    {
      immediate: true,
      deep: true,
    },
  )
</script>

<style scoped lang="less"></style>
